/*******************************************************************************
 * Copyright 2011 @ Kapil Viren Ahuja
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.kapilvirenahuja.eamsteps.dataprovider.impl;

import java.io.IOException;
import java.io.InputStream;

import jxl.Workbook;
import jxl.read.biff.BiffException;

import org.springframework.core.io.ClassPathResource;

import com.kapil.framework.logger.ILogger;
import com.kapil.framework.logger.LogFactory;
import com.kapilvirenahuja.eamsteps.common.DataProviderException;
import com.kapilvirenahuja.eamsteps.dataloader.IDataLoader;
import com.kapilvirenahuja.eamsteps.dataloader.impl.NativeDataLoader;
import com.kapilvirenahuja.eamsteps.dataloader.impl.ReferenceDataLoader;
import com.kapilvirenahuja.eamsteps.dataloader.impl.ResponseDataLoader;
import com.kapilvirenahuja.eamsteps.dataprovider.IDataProvider;
import com.kapilvirenahuja.eamsteps.datareader.IDataSet;
import com.kapilvirenahuja.eamsteps.datareader.excel.ExcelDataSet;
import com.kapilvirenahuja.eamsteps.form.IDataForm;
import com.kapilvirenahuja.eamsteps.parser.ExcelHeaderParser;
import com.kapilvirenahuja.eamsteps.parser.IHeaderParser;


/**
 * Factory to initialize a {@link IDataProvider}
 * 
 */
public final class DataProviderFactory
{
    private static final ILogger             logger   = LogFactory.getInstance().getLogger(DataProviderFactory.class);


    private static final DataProviderFactory INSTANCE = new DataProviderFactory();


    private DataProviderFactory()
    {
        // Made private to restrict instances from getting created.
    }


    public static DataProviderFactory getInstance()
    {
        return INSTANCE;
    }


    public IDataProvider getDefaultDataProvider(IDataForm form, String fileName)
    {
        IHeaderParser headerParser = new ExcelHeaderParser();

        IDataLoader responseDataLoader = new ResponseDataLoader();
        IDataLoader referenceDataLoader = new ReferenceDataLoader(responseDataLoader);
        IDataLoader nativeDataLoader = new NativeDataLoader(referenceDataLoader);

        IDataSet dataSet = initializeExcelWorkbook(fileName);

        return new DefaultDataProvider(dataSet, form, headerParser, nativeDataLoader);
    }


    /**
     * Used internally to load the Excel Workbook for a the given <code>fileName</code>. When passing the filename do
     * not add the suffix, as it is handled internally.
     * 
     * </br>
     * 
     * The Excel sheet should be in the class path and the fileName should represent the classpath and the filename.
     */
    private IDataSet initializeExcelWorkbook(String fileName)
    {
        try
        {
            logger.debug("Start load of Excel file ##.", fileName);
            ClassPathResource resource = new ClassPathResource(fileName + ".xls");

            InputStream stream = resource.getInputStream();
            Workbook workbook = Workbook.getWorkbook(stream);
            return new ExcelDataSet(workbook);
        }
        catch (IOException ioex)
        {
            throw new DataProviderException("Excel File [" + fileName + "] not found in the classpath.", ioex);
        }
        catch (BiffException bex)
        {
            throw new DataProviderException("Could not create the ExcelDataProvider from the file [" + fileName + "]", bex);
        }
    }
}
